<template>
	<view class="page">
		<view class="title">上传录制的音频</view>
		<view class="tip">为确保获得最佳训练效果，上传音频保持在5-10秒。</view>

		<!-- 选取音频 -->
		<view class="flex-between margin30 padding-row30">
			<view class="uploadBtn" @click="chooseAudioByWeChat()">选择音频上传</view>
			<view class="uploadBtn" @click="chooseAudioByRecorder()">录制音频上传</view>
		</view>

		<view class="inpVue margin30" v-if="fileUrl && fileName">
			<view class="label">当前上传音频</view>
			<view class="audioVue flex align-center margin20">
				<view class="playBtn relative" @click="uploadAudioPlayFun(fileUrl)">
					<image
						src=""
						style="width: 44rpx; height: 44rpx;" class="absolute-auto" v-if="!isUploadPlay"></image>
					<image
						src=""
						style="width: 44rpx; height: 44rpx;" class="absolute-auto" v-else></image>
				</view>
				<view class="flex-1 padding-row20 flex-between align-center">
					<text>{{ fileName }}</text>
					<image src="../../static/close.png" style="width: 40rpx; height: 40rpx;"
						@click="fileUrl=''; fileName='';"></image>
				</view>
			</view>
		</view>

		<!-- 设置声音名称 -->
		<view class="inpVue margin30">
			<view class="label">设置声音名称</view>
			<input type="text" placeholder="请设置声音名称" v-model="name" />
		</view>

		<!-- 性别选择 -->
		<view class="inpVue margin30">
			<view class="label">选择声音性别</view>
			<view class="margin20">
				<u-radio-group v-model="sex" active-color="#18AB4E">
					<u-radio v-for="(item, index) in sexes" :key="index" :name="item.name">{{item.name}}</u-radio>
				</u-radio-group>
			</view>
		</view>

		<!-- 开始训练按钮 -->
		<view class="inpVue margin30">
			<u-checkbox v-model="checked" active-color="#18AB4E" label-size="28"><text
					style="color: #81868e; line-height: 1;">公开训练后声音，可获得100积分用于合成视频</text></u-checkbox>
			<view class="startBtn margin20" @click="startFun()">开始训练</view>
			<view class="w100 flex-between align-center margin20">
				<text style="color: #81868e;">剩余训练额度：{{ availableQuota }}次</text>
				<text style="color: #18AB4E; text-decoration: underline;"
					@click="$tools.route('../mine/myVoice')">声音管理</text>
			</view>
		</view>

		<!-- 我的声音列表 -->
		<view class="myList margin50">
			<view class="title" style="padding: 0;">我的声音列表</view>
			<view class="margin20">
				<u-subsection :list="tabs" :current="current" button-color="#18AB4E" active-color="#fff"
					bg-color="#ececec" @change="change"></u-subsection>
			</view>
			<template v-if="current===0">
				<view class="item flex align-center margin20" v-for="(item, index) in list" :key="index">
					<view class="playBtn relative" @click="playFun(item.url, item.id)">
						<image
							src=""
							style="width: 44rpx; height: 44rpx;" class="absolute-auto" v-if="item.id!=audioId"></image>
						<image
							src=""
							style="width: 44rpx; height: 44rpx;" class="absolute-auto" v-else></image>
					</view>
					<view class="flex-1 flex-between padding-row20 align-center">
						<text style="color: #81868e;">{{ item.name }}-{{ item.sex }}</text>
						<u-icon name="trash-fill" size="42" color="#81868e" @click="deleteId = item.id; show = true" />
					</view>
				</view>
			</template>
			<template v-else>
				<view class="item flex align-center margin20" v-for="(item, index) in list" :key="index">
					<view class="playBtn relative" @click="$u.toast('声音正在训练中')">
						<image
							src=""
							style="width: 44rpx; height: 44rpx;" class="absolute-auto"></image>
					</view>
					<view class="progressVue">
						<u-line-progress active-color="#18AB4E" inactive-color="#ececec" :percent="item.progress"
							:striped="true" :striped-active="true" height="36"></u-line-progress>
					</view>
				</view>
			</template>
		</view>

		<!-- 删除声音 -->
		<u-modal v-model="show" content="确认删除该声音" confirm-color="#18AB4E" :show-cancel-button="true"
			@confirm="deleteSoundTrain"></u-modal>

		<!-- 录音 -->
		<u-popup v-model="isRecorder" mode="bottom" @close="close">
			<view class="recordVue" v-if="isRecorder">
				<view class="tit">请录制朗读如下文案：</view>
				<view class="text">大家好，请仔细听到我的语速和情感，我会快速而清晰的读出这句话：我来自湖北的测试员，正在测试语音识别功能。</view>
				<view class="tit margin20">训练要求：</view>
				<view class="text">-时长：5到10秒之间</view>
				<view class="text">-语言：普通话</view>
				<view class="text">-音质：咬字清晰明了，无多人声音，不结巴，少语气词</view>
				<view class="text">-文件格式： 音频文件格式</view>
				<view class="text">-上传音频的语速和情感将与最终推理合成想过相似，例如，上传语音语速快，合成时也会快</view>
				<view class="imgVue margin50">
					<image src="../../static/record1.png" style="width: 250rpx; height: 250rpx;" v-if="recording">
					</image>
					<image src="../../static/record.png" style="width: 250rpx; height: 250rpx;" v-else></image>
				</view>
				<view class="recordBtn margin50" @click="recordFun()">{{ recording ? "点击结束录音" : "点击开始录音"}}</view>
			</view>
		</u-popup>
	</view>
</template>

<script>
	import baseUrl from "@/common/url.js"
	import chooseFile from '@/common/chooseFile.js';
	export default {
		data() {
			return {
				name: "",
				fileName: "",
				fileUrl: "",
				sex: "男",
				sexes: [{
					name: "男"
				}, {
					name: "女"
				}],
				innerAudioContext: null,
				isUploadPlay: false,
				checked: false,
				availableQuota: 0,
				isPlay: false,
				audioId: 0,
				audioContext: null,
				list: [],
				tabs: [{
					name: "已完成"
				}, {
					name: "训练中"
				}],
				current: 0,
				record: '', // 全局唯一录音管理区
				isRecorder: false,
				recording: false, // 录音中
				deleteId: "",
				show: false,
				isAuth: null,
			}
		},
		async onLoad() {
			this.record = uni.getRecorderManager()
			this.canRecord()
			await this.getSoundQuota()
			await this.getList()
		},
		methods: {
			// 获取用户声音训练额度
			async getSoundQuota() {
				const res = await this.$request("/shuziren/soundQuota", {}, "GET")
				if (res.code === 200) this.availableQuota = res.data.availableQuota
			},

			// 删除声音
			async deleteSoundTrain() {
				const res = await this.$request("/shuziren/soundTrain", {
					id: this.deleteId
				}, "DELETE")
				if (res.code === 200) {
					this.getList();
					this.$u.toast("删除成功")
				} else {
					this.$u.toast(res.msg)
				}
			},

			change(e) {
				this.current = e
				this.getList()
			},

			close() {
				this.recording = false
				this.record.stop()
				this.isRecorder = false
			},

			// 开始训练声音
			async startFun() {
				if (this.availableQuota === 0) return this.$u.toast("请购买训练额度")
				if (!this.name) return this.$u.toast("请设置声音名称")
				if (!this.fileUrl) return this.$u.toast("请上传音频")
				uni.showLoading()
				const res = await this.$request("/shuziren/soundTrain/start", {
					name: this.name,
					sex: this.sex,
					isPublic: this.checked,
					url: this.fileUrl
				}, "POST", "application/json")
				if (res.code === 200) {
					uni.hideLoading()
					this.$u.toast("训练开始，请等稍等")
					this.name = ""
					this.fileUrl = ""
					this.availableQuota -= 1
					this.current = 1
					this.getList()
				} else {
					uni.hideLoading()
					this.$u.toast(res.msg)
				}
			},

			// 获取用户已完成训练的声音列表
			async getList() {
				let url = ["/shuziren/soundTrain/done", "/shuziren/soundTrain/training"][this.current]
				let data = this.current === 0 ? {
					sex: "全部"
				} : {}
				const res = await this.$request(url, data, "GET")
				if (res.code === 200) {
					this.list = res.data
					if (this.current === 1) {
						let pages = getCurrentPages();
						let curRoute = pages[pages.length - 1].route //获取当前页面路由
						if (curRoute === "pages/index/voice") {
							setTimeout(() => {
								if (this.list.length > 0) this.getList()
							}, 3000)
						}
					}
				}
			},

			// 播放列表音频
			playFun(url, id) {
				if (this.isUploadPlay) {
					this.innerAudioContext.pause();
					this.isUploadPlay = false
				}
				if (this.audioId && this.audioId != id) {
					this.audioContext.destroy()
					this.audioContext = null
					this.audioId = 0
				}
				if (this.audioId && this.audioId == id) {
					this.audioContext.destroy()
					this.audioContext = null
					this.audioId = 0
					return
				}
				this.audioId = id
				this.audioContext = uni.createInnerAudioContext();
				this.audioContext.autoplay = true;
				this.audioContext.src = url
				this.audioContext.onPlay(() => {
					console.log('开始播放');
				});
				this.audioContext.onEnded(() => {
					console.log('播放结束');
					this.audioId = 0
					this.audioContext.destroy()
					this.audioContext = null
				})
			},

			// 播放上传音频
			uploadAudioPlayFun(url) {
				if (!url) return
				if (this.audioId) {
					this.audioContext.destroy()
					this.audioContext = null
					this.audioId = 0
				}
				if (this.isUploadPlay) {
					this.innerAudioContext.pause();
					this.isUploadPlay = false
					return
				}
				this.isUploadPlay = true
				this.innerAudioContext = uni.createInnerAudioContext();
				this.innerAudioContext.autoplay = true;
				this.innerAudioContext.src = url
				this.innerAudioContext.onPlay(() => {
					console.log('开始播放');
				});
				this.innerAudioContext.onEnded(() => {
					console.log('播放结束');
					this.isUploadPlay = false
					this.innerAudioContext.destroy()
					this.innerAudioContext = null
				})
			},

			// 获取上传音频时长
			recordingDuration(name, url) {
				this.$request("/shuziren/soundTrain/getDuration", {
					prompt_wav: url
				}, "POST", "application/json").then(res => {
					if (res.code === 200) {
						let durationLimitation = res.data >= 5 && res.data < 10
						console.log("时长是否在范围内", durationLimitation, res.data)
						if (durationLimitation) {
							this.fileName = name
							this.fileUrl = url
							if (this.audioId === 0 && this.isUploadPlay) {
								this.innerAudioContext.destroy()
								this.innerAudioContext = null
								this.isUploadPlay = false
							}
						} else {
							this.$u.toast("上传音频保持在5-10秒")
						}
					}
				})
			},

			chooseAudioByRecorder() {
				this.isRecorder = true
			},

			canRecord() {
				let that = this
				uni.getSetting({
					success(res) {
						that.isAuth = res.authSetting['scope.record'];
						console.log("录音权限", that.isAuth)
					}
				});
			},

			authFun() {
				let that = this
				uni.authorize({
					scope: "scope.record",
					success() {
						uni.openSetting();
						that.canRecord()
					}
				})
			},

			// 开始录音 结束录音
			recordFun() {
				if (!this.isAuth) return this.authFun()
				if (this.isAuth == true) console.log("录音权限已开启")
				console.log(this.record.sampleRate, "kkkkk")
				if (this.recording) {
					console.log("录音结束")
					this.recording = false
					this.record.stop()
					this.isRecorder = false
					this.record.onStop(res => {
						const tempFilePaths = res.tempFilePath
						console.log(tempFilePaths)
						let that = this
						uni.uploadFile({
							url: baseUrl.url + "/aiet-file-center/file",
							filePath: tempFilePaths,
							name: "file",
							formData: {
								"path": "shuziren/audio"
							},
							success(uploadRes) {
								uni.hideLoading()
								let data = JSON.parse(uploadRes.data)
								console.log(data)
								if (data.code === 200) {
									console.log(new Date().getTime(), data.data.fileUrl)
									that.recordingDuration(new Date().getTime(), data.data.fileUrl)
								} else {
									that.$u.toast(data.msg)
								}
							},
							fail(uploadError) {
								console.log(uploadError)
								that.$u.toast("上传失败")
							}
						});
					})
				} else {
					this.recording = true
					this.record.start({
						sampleRate: 16000,
						format: "wav",
						duration: 10000,
						encodeBitRate: 96000,
						numberOfChannels: 1
					})
					console.log("开始录音")
				}
			},

			// 从微信中选择音频文件
			chooseAudioByWeChat() {
				let that = this
				wx.chooseMessageFile({
					extension: [".wav", ".mp3", ".m4a", ".amr"],
					success(res) {
						const tempFilePaths = res.tempFiles[0]
						console.log(tempFilePaths)
						uni.uploadFile({
							url: baseUrl.url + "/aiet-file-center/file",
							filePath: tempFilePaths.path,
							name: "file",
							formData: {
								"path": "shuziren/audio"
							},
							success(uploadRes) {
								uni.hideLoading()
								let data = JSON.parse(uploadRes.data)
								console.log(data)
								if (data.code === 200) {
									console.log(tempFilePaths.name, data.data.fileUrl)
									that.recordingDuration(tempFilePaths.name, data.data.fileUrl)
								} else {
									that.$u.toast(data.msg)
								}
							},
							fail(uploadError) {
								console.log(uploadError)
								that.$u.toast("上传失败")
							}
						});
					}
				})
			}
		}
	}
</script>

<style lang="less" scoped>
	.recordVue {
		width: 100vw;
		padding: 30rpx 30rpx 60rpx;

		.tit {
			color: #000;
			font-weight: 600;
			padding-bottom: 20rpx;
			line-height: 1;
		}

		.text {
			color: #81868e;
		}

		.imgVue {
			width: 250rpx;
			height: 250rpx;
			text-align: center;
		}

		.recordBtn {
			width: 520rpx;
			height: 88rpx;
			line-height: 88rpx;
			text-align: center;
			background: #18AB4E;
			border-radius: 12rpx;
			color: #fff;
		}
	}

	.title {
		color: #000;
		font-weight: 600;
		font-size: 30rpx;
		padding: 30rpx 0 0 30rpx;
		line-height: 1;
	}

	.tip {
		color: #81868e;
		padding: 20rpx 30rpx 0 30rpx;
	}

	.uploadBtn {
		width: 330rpx;
		height: 88rpx;
		border-radius: 12rpx;
		line-height: 88rpx;
		text-align: center;
		color: #fff;
		background: #18AB4E;
	}

	.inpVue {
		width: 690rpx;

		.label {
			color: #000;
			font-weight: 600;
			font-size: 30rpx;
		}

		.audioVue {
			width: 100%;
			height: 80rpx;
			border: 1rpx solid #EBEDED;
			border-radius: 12rpx;

			.playBtn {
				width: 80rpx;
				height: 80rpx;
				background: #EBEDED;
				border-radius: 12rpx 0 0 12rpx;
			}
		}

		input {
			width: 100%;
			height: 88rpx;
			border: 1rpx solid #EBEDED;
			border-radius: 12rpx;
			margin-top: 12rpx;
			padding-left: 20rpx;
			font-size: 28rpx;
			box-sizing: border-box;
		}

		.startBtn {
			width: 100%;
			height: 88rpx;
			background: #18AB4E;
			border-radius: 12rpx;
			line-height: 88rpx;
			text-align: center;
			color: #fff;
		}
	}

	.myList {
		width: 690rpx;
		padding-bottom: 30rpx;

		.item {
			width: 100%;
			height: 80rpx;
			border: 1rpx solid #EBEDED;
			border-radius: 12rpx;

			.playBtn {
				width: 80rpx;
				height: 80rpx;
				background: #EBEDED;
				border-radius: 12rpx 0 0 12rpx;
			}

			.progressVue {
				flex: 1;
				padding: 0 30rpx
			}
		}
	}
</style>